/*
 * Copyright (C) 2012 POAS.VSTU
 */
package ui;

import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import javax.swing.event.EventListenerList;

import model.*;

/**
 * Кон как графический элемент.
 * На самом деле он не имеет своего представления - это участок игровой панели,
 * занятый картами
 */
public class UICardPileKitty extends UICardPile implements MouseListener{

    /** Список слушателей событий UI кона. */
    protected EventListenerList listenerList = new EventListenerList();

    /** Модель кона, с которой связано данное представление */
    protected CardPileKitty mModel;

    /** Зазор между левой и правой частями кона */
    private int mGap;

    public UICardPileKitty(CardPileKitty pileKitty, JPanel gamePanel) {
        super(pileKitty, (UIGamePanel)gamePanel);
        mModel = pileKitty;
        mGap = 20;
    }

    /**
     * Выбирает карту на кону для просмотра
     * @param card
     */
    public void choose(UICard card) {

        card.actionMoveTo(new Point(card.getLocation().x, card.getLocation().y - 20), MovementSpeed.NORMAL, 0);
        card.actionTurnFaceUp(0);
        try {
            mPanel.executeMovements();
        } catch (InterruptedException ex) {
            Logger.getLogger(UICardPileKitty.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public void cancelCardChoice(UICard card){

        card.actionTurnFaceDown(0);
        card.actionMoveTo(new Point(card.getLocation().x, card.getLocation().y + 20), MovementSpeed.NORMAL, 0);
 
        try {
            mPanel.executeMovements();
        } catch (InterruptedException ex) {
            Logger.getLogger(UICardPileKitty.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Добавляет карты из правой части кона в левую.
     */
    private void mergeParts() {

        UICard uiCard;
        int iCard = 0;
        int posX = 0;
        int posY = 0;

        for(Card card: mModel.leftPart()) {
            uiCard = mPanel.getUICard(card);
            uiCard.actionTurnFaceDown(0);
            posX = getLocation().x + iCard*(uiCard.getWidth()/6);
            posY = getLocation().y;
            uiCard.actionMoveTo(new Point(posX, posY), MovementSpeed.NORMAL, 0);
            iCard++;
        }
    }

    /**
     * Подтаскивает карты к стопке, чтобы их можно было поместить в стопку,
     * визуализирует этот процесс.
     * @param cards перетаскиваемые карты
     */
    @Override
    public void dragIn(CardPile cards) {
        
        UICard uiCard;
        Point destination;
        try {
            mPanel.executeMovements();
        } catch (InterruptedException ex) {
            Logger.getLogger(UICardPileKitty.class.getName()).log(Level.SEVERE, null, ex);
        }
        for(Card card: cards) {
            uiCard = mPanel.getUICard(card);
            uiCard.actionTurnFaceDown(0);
            destination = new Point(getLocation().x + 36 * uiCard.getWidth()/6, getLocation().y);
            uiCard.actionMoveTo(destination, MovementSpeed.NORMAL, 0);
            uiCard.actionSetOrientation(getOrientation(), 0);
        }
    }

    /**
     * Помещает заданные карты в стопку, визуализирует этот процесс.
     * @param cards добавлемые карты
     */
    @Override
    public void push(CardPile cards) {
        UICard uiCard;
        int iCard = 0;
        int dx = 0;
        int posX = 0;
        int posY = 0;

        mergeParts();

        for(Card card: cards) {

            uiCard = mPanel.getUICard(card);
            uiCard.setZOrder(0);
            dx = uiCard.getWidth()/6*iCard;

            posX = getLocation().x + mGap + 36 * uiCard.getWidth()/6 - dx;
            posY = getLocation().y;
            uiCard.actionMoveTo(new Point(posX, posY), MovementSpeed.NORMAL, 0);
            
            iCard++;
        }
        try {
            mPanel.executeMovements();
        } catch (InterruptedException ex) {
            Logger.getLogger(UICardPileKitty.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Задает величину зазора между левой и правой частями кона
     * @param gap - величина зазора
     */
    public void setGap(int gap){
        mGap = gap;
    }

    /** Сделать последние выложенные на кон карты доступными для игрока-человека.*/
    public void activateLastCards() {
        for (Card card: mModel.rightPart()) {
            mPanel.getUICard(card).setClickable(true);
        }
    }

    /** Сделать последние выложенные на кон карты недоступными для игрока-человека.*/
    public void deactivateLastCards() {
        for (Card card: mModel.rightPart()) {
            mPanel.getUICard(card).setClickable(false);
        }
        for (Card card: mModel.leftPart()) {
            mPanel.getUICard(card).setClickable(false);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getSource() instanceof UICard) {
            UICard card = (UICard) e.getSource();
            if(card.isClickable() && ((CardPileKitty)getModel()).rightPart().contains(card.getModel())) {
                firePlayerCheckedCardEvent(mPanel.getModel().getAllPlayers().get(0), card.getModel());
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    /**
     * Добавить слушателя событий.
     * @param l добавляемый слушатель событий
     */
    public void addGameProcessEventListener(GameProcessEventListener l) {
        listenerList.add(GameProcessEventListener.class, l);
    }

    /**
     * Удаление слушателя событий.
     * @param l слушатель, которого нужно забыть
     */
    public void removeGameProcessEventListener(GameProcessEventListener l) {
        listenerList.remove(GameProcessEventListener.class, l);
    }

    /**
     * Испустить событие "игрок выбрал для проверки карту на кону".
     * @param player игрок
     * @param card карта
     */
    public void firePlayerCheckedCardEvent(Player player, Card card) {
        GameProcessEvent event = GameProcessEvent.playerChecksCard(this, player, card);
        Object[] listeners = listenerList.getListeners(GameProcessEventListener.class);
        for (int i = 0; i < listeners.length; i++) {
            ((GameProcessEventListener)listeners[i]).playerCheckedCard(event);
        }
    }
}
